Abraxus's Blog

RaRCTF Dotty Write Up

Details:

Jeopardy style CTF

Category: Reverse Engineering

Points: 150

Comments: My new program will keep your secrets safe using military grade encryption!

Write up:

Running the file command on dotty.exe we can see that it is a .NET assembly so I opened the file using dnSpy:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Dotty
{
	// Token: 0x02000002 RID: 2
	internal class Program
	{
		// Token: 0x06000002 RID: 2 RVA: 0x00002058 File Offset: 0x00000258
		private static string Dotter(string phrase)
		{
			return string.Join("|", from char c in phrase
			select Program.mapper[char.ToUpper(c)]);
		}

		// Token: 0x06000003 RID: 3 RVA: 0x0000208C File Offset: 0x0000028C
		private static void Main(string[] args)
		{
			Console.Write("Please enter your secret to encode: ");
			string phrase = Console.ReadLine();
			string text = Program.Dotter(phrase);
			if (text == Check.check)
			{
				Console.WriteLine("That's the right secret!");
			}
			else
			{
				Console.WriteLine(text);
			}
		}

		// Token: 0x04000001 RID: 1
		private static Dictionary<char, string> mapper = new Dictionary<char, string>
		{
			{
				' ',
				"/"
			},
...
			{
				'0',
				"-----"
			}
		};
	}
}
using System;

namespace Dotty
{
	// Token: 0x02000003 RID: 3
	internal class Check
	{
		// Token: 0x04000003 RID: 3
		public static string check = "-|....|.|/|..-.|.-..|.-|--.|/|..|...|/|---|.---|--.-|-..-|.|-.--|...--|..-|--|--..|.....|.--|..|--|.-..|.|.-..|.....|....-|-|.-|.....|-.-|--...|---|.-|--..|-|--.|..---|..---|--...|--.|-...|--..|..-.|-....|-.|.-..|--.-|.--.|.|--...|-|-....|.--.|--..|--...|.-..|.....|-|--.|-.-.|-.|-..|-...|--|--|...--|-..|.-|-.|.-..|.....|/|-...|.-|...|.|...--|..---";
	}
}

From this I could see that check was the flag in it's encrypted form. So what I did was extract the dictionary and write a script to convert the flag back to text:

# flag string
flag = "-|....|.|/|..-.|.-..|.-|--.|/|..|...|/|---|.---|--.-|-..-|.|-.--|...--|..-|--|--..|.....|.--|..|--|.-..|.|.-..|.....|....-|-|.-|.....|-.-|--...|---|.-|--..|-|--.|..---|..---|--...|--.|-...|--..|..-.|-....|-.|.-..|--.-|.--.|.|--...|-|-....|.--.|--..|--...|.-..|.....|-|--.|-.-.|-.|-..|-...|--|--|...--|-..|.-|-.|.-..|.....|/|-...|.-|...|.|...--|..---"

# mapped dictionary
mapped = [[ ' ', "/" ], [ 'A', ".-" ], [ 'B', "-..." ], [ 'C', "-.-." ], [ 'D', "-.." ], [ 'E', "." ], [ 'F', "..-." ], [ 'G', "--." ], [ 'H', "...." ], [ 'I', ".." ], [ 'J', ".---" ], [ 'K', "-.-" ], [ 'L', ".-.." ], [ 'M', "--" ], [ 'N', "-." ], [ 'O', "---" ], [ 'P', ".--." ], [ 'Q', "--.-" ], [ 'R', ".-." ], [ 'S', "..." ], [ 'T', "-" ], [ 'U', "..-" ], [ 'V', "...-" ], [ 'W', ".--" ], [ 'X', "-..-" ], [ 'Y', "-.--" ], [ 'Z', "--.." ], [ '1', ".----" ], [ '2', "..---" ], [ '3', "...--" ], [ '4', "....-" ], [ '5', "....." ], [ '6', "-...." ], [ '7', "--..." ], [ '8', "---.." ], [ '9', "----." ], [ '0', "-----" ]  ]

# split the flag the way the program does it
flag = flag.split("|")

s = ""

# go through and convert the flag
for i in flag:
	for j in mapped:
		if i == j[1]:
			s += j[0]
			break	


print(s)

When run this pritned out:

THE FLAG IS OJQXEY3UMZ5WIMLEL54TA5K7OAZTG227GBZF6NLQPE7T6PZ7L5TGCNDBMM3DANL5 BASE32

When converted from BASE32 I got:

rarctf{d1d_y0u_p33k_0r_5py????_fa4ac605}